package com.hyq.learn.web.exception;

import com.google.common.base.Joiner;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author : chenzetao
 * @since : 2023/3/9
 */
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class LearnQuestBasicErrorController extends BasicErrorController {

    public LearnQuestBasicErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties) {
        super(errorAttributes, serverProperties.getError());
    }

    @Override
    @RequestMapping
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        HttpStatus status = getStatus(request);
        if (status == HttpStatus.NO_CONTENT) {
            return new ResponseEntity<>(status);
        }
        Map<String, Object> originalMap = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
        String errorMessage = Optional.ofNullable(originalMap)
                .map(map -> map.entrySet().stream()
                        .map(entry -> entry.getKey() + "=" + entry.getValue())
                        .collect(Collectors.toList())
                ).map(list -> Joiner.on(", ").join(list))
                .orElse(StringUtils.EMPTY);
        Map<String, Object> responseMap = new HashMap<>();
        responseMap.put("error_code", "9999");
        responseMap.put("error_message", errorMessage);
        return new ResponseEntity<>(responseMap, status);
    }

    @Override
    @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
        HttpStatus status = getStatus(request);
        Map<String, Object> model = Collections
                .unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = resolveErrorView(request, response, status, model);
        if (modelAndView != null) {
            return modelAndView;
        }
        if (status == HttpStatus.NOT_FOUND) {
            return new ModelAndView("404.html", model);
        }
        return new ModelAndView("error", model);
    }

}
